package bg.btanev.eightyfour.client.presenter;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import bg.btanev.eightyfour.client.service.GWTCommandServiceAsync;
import bg.btanev.eightyfour.shared.command.CommandResult;
import bg.btanev.eightyfour.shared.command.profileevent.FindProfileEventsInput;
import bg.btanev.eightyfour.shared.command.target.FindTagsForTargetCommand;
import bg.btanev.eightyfour.shared.command.target.FindTagsForTargetInput;
import bg.btanev.eightyfour.shared.dto.TagDto;
import bg.btanev.eightyfour.shared.dto.TargetDto;
import bg.btanev.eightyfour.shared.state.ProfileType;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasWidgets;

/**
 *
 * @author B.Tanev
 *
 */
public class ProfileEventsSearchPresenter implements Presenter {

	public static interface ProfileEventsSearchDisplay extends Display {

		HasValue<Date> getBeginDate();

		HasValue<Date> getEndDate();

		HasText getQueryData();

		HasClickHandlers getClearButton();

		HasClickHandlers getSearchButton();

		TagDto getSelectedTag();

		ProfileType getSelectedProfileType();

		void clearView();

		void setTagsData(List<TagDto> tags);
	}

	@SuppressWarnings("unchecked")
	private final GWTCommandServiceAsync rpcService;
	private final ProfileEventsSearchDisplay display;
	private final TargetDto target;

	private final Set<ProfileEventsSearchListener> searchListeners = new HashSet<ProfileEventsSearchListener>();

	@SuppressWarnings("unchecked")
	public ProfileEventsSearchPresenter(GWTCommandServiceAsync rpcService, ProfileEventsSearchDisplay display,
			TargetDto target) {
		super();

		this.rpcService = rpcService;
		this.display = display;
		this.target = target;

		this.display.getSearchButton().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				performSearchProfileEventsRequest();
			}
		});
	}

	private void performSearchProfileEventsRequest() {
		Date beginDate = this.display.getBeginDate().getValue();
		Date endDate = this.display.getEndDate().getValue();
		TagDto tag = this.display.getSelectedTag();
		String queryText = this.display.getQueryData().getText();
		ProfileType profileType = this.display.getSelectedProfileType();

		FindProfileEventsInput input = new FindProfileEventsInput();
		input.setTarget(target);
		input.setBeginDate(beginDate);
		input.setEndDate(endDate);
		input.setProfileType(profileType);

		if (tag != null) {
			ArrayList<TagDto> tags = new ArrayList<TagDto>();
			tags.add(tag);
			input.setTags(tags);
		}

		if (queryText != null) {
			queryText = queryText.trim();
			if (queryText.length() > 0) {
				input.setQuery(queryText);
			}
		}
		notifySearchListeners(input);
	}

	public void addSearchListener(ProfileEventsSearchListener listener) {
		if (listener != null) {
			searchListeners.add(listener);
		}
	}

	private void notifySearchListeners(FindProfileEventsInput input) {
		for (ProfileEventsSearchListener listener : searchListeners) {
			listener.onNewSearchRequest(input);
		}
	}

	@Override
	public void go(HasWidgets container) {
		container.clear();
		container.add(display.asWidget());
		loadTags();
	}

	@SuppressWarnings("unchecked")
	private void loadTags() {
		FindTagsForTargetInput input = new FindTagsForTargetInput();
		input.setTarget(target);
		FindTagsForTargetCommand command = new FindTagsForTargetCommand();
		command.setInput(input);
		rpcService.executeCommand(command,
				new AsyncCallback<CommandResult<FindTagsForTargetInput, ArrayList<TagDto>>>() {

					@Override
					public void onFailure(Throwable caught) {
						display.setTagsData(null);
					}

					@Override
					public void onSuccess(CommandResult<FindTagsForTargetInput, ArrayList<TagDto>> result) {
						if (result != null) {
							List<TagDto> tags = result.getResult();
							display.setTagsData(tags);
						}
					}
				});
	}

	public static interface ProfileEventsSearchListener {
		void onNewSearchRequest(FindProfileEventsInput input);
	}
}
